package MBO;

//import java.lang.StringBuilder;
import java.util.ArrayList;
import java.lang.Math;

import Utilities.MBOInfo;
import Utilities.OperatorSchedule;
import Utilities.TrainInfo;
//import CTCOffice.Schedule;
//import CTCOffice.Scheduler;

public class MBO implements CTCOfficetoMBO,TrainControllertoMBO
{

	public double service_brake=1.2*3.28084;// in ft/s
	public int car_len=106;
	public int mboAuthority;
	public double mboSpeed;
	public int trainId;
	public int passengers;
	public int currx;
	public int curry;
	public int nextx;
	public int nexty;
	public int compx;
	public int compy;
	public int speed;
	public int locTrainID;
	public ArrayList<Double> newSpeed;
	public ArrayList<Integer> newAuthority;
	public ArrayList<Integer> trainID;
	public double shortdist;
	public double currdist;
	public int closestTrain;
	ArrayList<TrainInfo> trainInfoList;
	//ArrayList<Schedule> trainSchedule;
	public ArrayList<String> times;
	public ArrayList<Integer> tsTrainID;
	public ArrayList<Integer> destination;
	public ArrayList<Integer> operator;
	public ArrayList<Integer> hour;
	public ArrayList<Integer> minute;
	public int op;
	public int tstid;//train schedule train id
	public int tstidnext;
	public int initialhour;
	public int initialminute;
	public int combinedTime;
	public int nexthour;
	public int nextminute;
	public int stationDropoff;
	public int breakendhour;
	public int breakendminute;
	public int posshour;
	public int possminute;
	public int breakout;

	public MBO()
	{
		trainInfoList = new ArrayList<TrainInfo>();//create object from train controller
		//trainSchedule= new ArrayList<Schedule>();
	
	}


	public void tick()
	{
		//receive trainInfo
		
		newSpeed=new ArrayList<Double>();//generate arraylists that will pass to train controller
		newAuthority=new ArrayList<Integer>();
		trainID=new ArrayList<Integer>();
		newSpeed.clear();
		newAuthority.clear();
		trainID.clear();
		stationDropoff=0;
		//TrainInfo trainInfo= new TrainInfo();
		//x=trainInfo.xCord;
		//y=trainInfo.yCord;
		//tID=trainInfo.trainID;
		//p=trainInfo.passengers;
		//sp=trainInfo.speed;//comes in at mph
		//numberOfTrains=tID.size();
		
		
		//create if(boolean), when true MBO MODE ON
		for(int a=0; a< trainInfoList.size(); a++)
		{
			TrainInfo ti = trainInfoList.get(a);
			currx=ti.xCord;
			curry=ti.yCord;
			shortdist=0;
			closestTrain=0;
			for(int b = 0; b < trainInfoList.size(); b++)
			{
				TrainInfo ti2=trainInfoList.get(b);
				nextx=ti2.xCord;
				nexty=ti2.yCord;
			
				if((curry!=359 || nexty!=405) && (nexty!=359 || curry!=405) && (currx!=594 || nextx!=555) && (nextx!=594 || currx!=555) || (curry==359 && nexty==359) || (curry==405 && nexty==405) || (currx==594 && nextx==594) || (currx==555 && nextx==555))
				{
					if(currx!=nextx || curry!=nexty)
					{
						if(nextx>currx)
						{
							compx=nextx-currx;
						}
						else
						{
							compx=currx-nextx;
						}
						if(nexty>currx)
						{
							compy=nexty-curry;
						}
						else
						{
							compy=curry-nexty;
						}
						if(shortdist==0)
						{
							shortdist=(compx*compx)+(compy*compy);
						}
						currdist=(compx*compx)+(compy*compy);
						if(currdist<=shortdist)
						{
							shortdist=currdist;
							closestTrain=ti2.trainID;
						}	
					}	
				}			
			}
			
			shortdist=Math.sqrt(shortdist);
			mboSpeed=ti.speed;
			mboAuthority=(int)(((mboSpeed*5280/3600)*(mboSpeed*5280/3600))/(2*(int)Math.round(service_brake)))+(car_len/2);
			if(mboAuthority<((shortdist-car_len/2)*0.5))
			{
				mboSpeed++;
			}
			if(mboAuthority>((shortdist-car_len/2)*0.8))
			{
				mboSpeed=mboSpeed-2;
			}	
			newSpeed.add(mboSpeed);
			newAuthority.add(mboAuthority);
			trainId=ti.trainID;
			trainID.add(trainId);
	
		}

		
		
		//create if(boolean), create operator schedule
		//if(generateOperatorSchedule=true)
		//{
		operator=new ArrayList<Integer>(100);
		op=1;
		//operator.add(50, op);
		times=new ArrayList<String>();
		tsTrainID=new ArrayList<Integer>();
		destination=new ArrayList<Integer>();
		hour=new ArrayList<Integer>();
		minute=new ArrayList<Integer>();
		
		
		////IMPLEMENT THIS TO PULL FROM MIKE TO GET TRAIN SCHEDULE
		
		/*for(Schedule s: Scheduler.getSchedules())
		{
			for(Destination d: s.getStops())
			{
				times.add(d.getArrival());
				destination.add(d);
				
			}
			tsTrainID.add(s.getTrainID());
		}*/
		
		breakout=0;
		
		for(int r=0; r<=times.size(); r++)
		{
			String string=times.get(r);
			String[] parts=string.split(":");
			String thehour= parts[0];
			String theminute=parts[1];
			int hours=Integer.parseInt(thehour);
			int minutes=Integer.parseInt(theminute);
			hour.add(hours);
			minute.add(minutes);	
		}
		
		for(int i=0; i<tsTrainID.size(); i++)
		{
			if(operator.get(i)==null)
			{
				//do another if statement. if the train id has already been used it is already in motion
				
				tstid=tsTrainID.get(i);
				initialhour=hour.get(i);
				initialminute=minute.get(i);
				combinedTime=0;
				for(int j=0; combinedTime<240;j++)
				{
					nexthour=hour.get(j);
					nextminute=minute.get(j);
					combinedTime=combinedTime+((nexthour*60)-(initialhour*60))+(nextminute-initialminute);
					if(combinedTime<=4)
					{
						operator.add(op);
						stationDropoff++;
					}
					if(combinedTime>240)
					{
						combinedTime=combinedTime-(nexthour-initialhour)-(nextminute-initialminute);
						break;
					}
					initialhour=nexthour;
					initialminute=nextminute;
				}
				//drop conductor off after 4 hour time
				combinedTime=combinedTime+30;
				
				breakendhour=combinedTime/60+initialhour;
				breakendminute=combinedTime%60+initialminute;
				if(breakendminute>=60)
				{
					breakendhour=breakendhour+1;
					breakendminute=breakendminute-60;
				}
				
				for(int k=stationDropoff;k<tsTrainID.size();k++)
				{
					if(destination.get(k)==destination.get(stationDropoff))
					{
						//its the right station. is it the expected time
						posshour=hour.get(k);
						possminute=minute.get(k);
						if((posshour==breakendhour && possminute==breakendminute) || (((breakendhour*60+breakendminute)<(posshour*60+possminute)) && ((posshour*60+possminute)<=(breakendhour*60+breakendminute+60))))		
						{
							combinedTime=0;
							initialhour=posshour;
							initialminute=possminute;
							for(int j=k; combinedTime<240;j++)
							{
								nexthour=hour.get(j);
								nextminute=minute.get(j);
								combinedTime=combinedTime+((nexthour*60)-(initialhour*60))+(nextminute-initialminute);
								if(combinedTime<=4)
								{
									operator.add(j, op);
									stationDropoff++;
								}
								if(combinedTime>240)
								{
									combinedTime=combinedTime-(nexthour-initialhour)-(nextminute-initialminute);
									breakout=1;
									break;
								}
								initialhour=nexthour;
								initialminute=nextminute;
							}
						}
					}
					
					if(breakout==1)
					{
						breakout=0;
						break;
					}
				}
				
				op++;
				
			}
		}
		
		
		//}
		
		//receive broken rail info
		//BrokenRailInfo brokenRailInfo= new BrokenRailInfo(block);
		//get the info from other members to determine op schedule and speed/auth
	}

	
	//send the info out
	public OperatorSchedule sendOperatorSchedule()
	{
		return null;
	}
	
	public void SendMBOInfoTrain(MBOInfo mboInfo)
	{
		
	}
	
	public void sendTrainInfo( TrainInfo ti )
	{
		trainInfoList.add(ti.trainID, ti);
	}
	
	/*public void sendTrainSchedule(Schedule sch)
	{
		trainSchedule.add(sch.trainID, sch);
	}*/
	
}